Document:       mfsps_serial.txt
Author:         Dimitris Zaharopoulos (zaxad@ergonous.gr)
Publisher:      Micrelec S.A.
Release:        02.24
Copyright:      Copyright (C) 2003 Micrelec S.A
Status:         Pre-final


              Communication Protocol Specification for MICRELEC 
                       Serial Fiscal Signature Devices



*******************************************************************************
What's new in version 2.24
*******************************************************************************
  * Added 'X by range' command [6.13a]
  * Added check for invalid chars in data stream
  * Added new error message (bad character in stream) [7.1]
  * Added valid/invalid stream data table [7.4]

*******************************************************************************
What's new in version 2.23
*******************************************************************************
  * Added 'Z closure no' field in 'read signature entry' command [6.11]
  * Added new parameter value '2' at 'XZ report' command [6.13]
  * Added new error message (closure date warning) [7.1]

*******************************************************************************
What's new in version 2.21
*******************************************************************************
  * Added new 'Read header' command [6.1a].
  * Added 'Next Z number' field in 'End of signature block' and 'Cancel 
    signature block' command replies [6.10], [6.10a].
  * Added 'remaining daily signatures' field in 'Summary status info' command
    reply [6.12a].
  * Added new error message '0x23' [7.1].


Table of contents
1......................................................Purpose of this document
2.........................................................................Goals
3......................................Design approach and compatibility issues
3.1.........................................................Further information
4...........................................................Communications line
5...........................................................Protocol discussion
5.1...................................................Model of data interchange
5.2..........................................................States of protocol
5.2.1........................................States definition -> Enquire state
5.2.2...................................States definition -> Verify acknowledge
5.2.3....................................States definition -> Acknowledge state
5.2.4............................States definition -> Packet transmittion state
5.2.5...............................States definition -> Packet reception state
5.3................................................Packet purpose and structure
5.3.1.....................................Packet verification - error detection
5.3.2.......................................................Fields - discussion
5.3.3..........................................................Fields - Classes
5.3.4..................................................Fields - types in detail
5.4..................................Request/Reply packets - Further discussion
6.................................................................Packet groups
6.1.....................................Packets in detail -> Program header [H]
6.1a.......................................Packets in detail -> Read header [h]
6.2...............Packets in detail -> Program the Real-Time Clock/Calendar [T]
6.3..................Packets in detail -> Read the Real-Time Clock/Calendar [t]
6.4.................................Packets in detail -> Read Device ID/S-N [a]
6.5....................................Packets in detail -> Display message [7]
6.6.......................................Packets in detail -> Read Version [v]
6.7.................................Packets in detail -> Read Device Status [?]
6.8..............................Packets in detail -> Begin signature block [{]
6.9.........................................Packets in detail -> Sign block [*]
6.9a...................................Packets in detail -> Sign text block [@]
6.9b.........................Packets in detail -> Sign base64 encoded block [&]
6.10............................Packets in detail -> End of signature block [}]
6.10a............................Packets in detail -> Abort signature block [^]
6.11..............................Packets in detail -> Read signature entry [$]
6.12a..............................Packets in detail -> Summary status info [Z]
6.12b................................Packets in detail -> Read closure data [R]
6.13.........................................Packets in detail -> XZ report [x]
6.13a.......................................Packets in detail -> X by range [X]
6.14......................Packets in detail -> Fiscal report (date to date) [f]
6.15............................Packets in detail -> Fiscal report (Z to Z) [z]
7...........................................Tables and miscelaneous definitions
7.1......................................... Table 1, Reply codes / error codes
7.2..........................................Table 2, ASCII control codes [CC1]
7.3..........Table 3, timeouts and retransmittions - minimum recommended values
7.4........................Table 4, Hexadecimal matrix of invalid binary values


*******************************************************************************
1. Purpose of this document
*******************************************************************************
  The purpose  of this document is to provide the necessary specification 
to software designers interested in communicating directly with all MICRELEC
compatible fiscal signature devices with a serial (RS232) interface.
This document assumes that the reader is familiar with basic serial 
communication concepts, such as transmitions, receptions, timeouts, etc.



*******************************************************************************
2. Goals
*******************************************************************************
  The developer will have all necessary information for implementing the 
protocol, and be able to:

   - Produce a SHA-1 digital signature for any number of invoices.
   - Update the device's list of daily signatures in case of fatal failure.
   - Issue the supported reports by protocol commands.


*******************************************************************************
3. Design approach and compatibility issues
*******************************************************************************
  Developers should take into concideration future additions or expansions
to this specification. The goal is that an application designed using an
older revision spec will function correctly with a device using a newer 
revision protocol. In order to do so, the developers *must* check responces 
only for the presence of the known information and 'quietly' discard the 
information that is unknown. The designers of this protocol guarantee that 
the extensions of this protocol will not alter the position or the type of 
the information (unless absolutely unavoidable). Extra fields will always be
added to the right of the reply strings. Specifically, these are the rules 
that deliver the highest compatibility:

   a) Check the protocol version number. This information guarantees
      safety towards new commands. For example (hypothetically): 
      In protocol revision '01.02' and higher the command '#' is supported, 
      so reading a revision '01.00' indicates that the command '#' will
      fail.

   b) Always assume correct a reply that has more fields than expected.
      For example:
      Reply expected: "AAAAA/BBBB/CCCC/"
      Reply received: "AAAAA/BBBB/CCCC/DDDDD"
      (Field 'DDDDD' is unexpected, but should not generate an error
      because all the expected fields are present. So this field
      *should* be silently discarded.)

   c) It is an excellent design approach not to be very strict with numerical
      ranges or string lengths expected (unless this specification requires 
      so). This guarantees that the application will be compatible with other 
      devices that use this protocol, but having different resources to operate
      with. For example, a different printer mechanism may limit, for example, 
      a header line length. Having a flexible design promises maximum 
      compatibility with different hardware requiring very little (or no) 
      changes to application source code.




*******************************************************************************
3.1. Further information
*******************************************************************************
  The implementors are encouraged to study and/or use parts of code examples
which are part of this document. Also they must keep informed of any changes 
in this specification due to the status of this document.  Suggestions from 
developers may or may not influence details of the document until it reaches
'final' status. 



*******************************************************************************
4. Communications line
*******************************************************************************
  The device communicates with host computer via an asyncronous serial line
of the RS-232C recommended standard. The serial line parameters are:

   - Baud rate:         115200 baud
   - Parity:            none
   - Data:              8
   - Stop:              1
   - Flow control:      none
  
  Note that because there is no flow control, only the RX/TX/GND signals are
required for the cable configuration. The maximum length of cable is described 
in the 232C recommended standard for this baud rate. It is highly recommended
that the maximum length is not exceeded to prevent drops in communication 
rate and undesirable retransmitions due to errors, or in worst case a total 
communication failure. When cable distance is unavoidably long, an extender
may be used. Also note that some devices may have programmable baud rate.



*******************************************************************************
5. Protocol discussion
*******************************************************************************

*******************************************************************************
5.1. Model of data interchange
*******************************************************************************
  The device uses the following model for communicating with the host:

             Sender(host)                  Receiver(device)
        ---------------------------------------------------------
               IDLE                        IDLE
            ENQUIRE ---------------------> 
                    <--------------------- ACKNOWLEDGE
             PACKET ---------------------> 
                    <--------------------- ACKNOWLEDGE
                    <--------------------- PACKET
        ACKNOWLEDGE --------------------->
               IDLE                        IDLE

  This scheme although describes the typical flow of data between the two
communicating sides (device and host computer) does not include any other
situation such as errors in transmition, retransmition etc. 
  Observe that this model includes two different packet transmitions, one
from sender to receiver and one from receiver to sender. In the paragraphs to
follow we will call the first 'request packet' and the second one 'reply
packet' for simplicity. Reply packets are always sent by the device when 
receiving command protocol requests. 



*******************************************************************************
5.2. States of protocol
*******************************************************************************
  For a better understanding of the previous paragraph and the communication
  flow, we can define states which communication 'sides' will enter. 

   - Idle state
     This is the state before any communication attempt takes place.

   - Enquire state
     The side that wishes to initiate communication sends an inquiry (in this 
     case, always the host side). The process of sending this inquiry is the 
     enquire state.

   - Acknowledge state
     The receiver will enter this state right after receiving an inquiry or 
     after the verification of a request packet. The sender will enter this 
     state after the verification of a reply packet.

   - Verify acknowledge state
     The sender or receiver will enter this state after an enquire state or a 
     packet transmittion state. The process of waiting the other end's positive
     or negative response is the verify acknowledge state.

   - Packet transmittion state
     The sender will enter this state to transmit a request packet and the 
     receiver to transmit a reply packet.

   - Packet reception state
     The receiver enters this state after acknowledging the sender's enquire to
     get the request packet. The sender will enter this state right after 
     verifying a positive acknowledge from the receiver, and only if the 
     specific protocol case requires a reply packet.


  Considering the above, the state flow for the sender and the receiver 
  in a typical communication attempt will be:

   --------------------------------------------------------------------
   Sender                                     Receiver
   --------------------------------------------------------------------
   Idle                                       Idle
   Enquire state / Verify ack. state          Acknowledge state
   Packet transmittion state                  Packet reception state
   Verify acknowledge state                   Acknowledge state
   Packet reception state                     Packet transmittion state
   Acknowledge state                          Verify acknowledge state
   Idle                                       Idle
   --------------------------------------------------------------------




*******************************************************************************
5.2.1. States definition -> Enquire state
*******************************************************************************
  The enquire state is actualy the transmittion of a single ascii control 
code ENQ [CC1] by the sender. Doing this, the sender has concluded the enquire
state. The purpose of this state is to find out if the receiver is able to 
reply, without flooding the communication line with too much data. After 
sending the ENQ code, the sender must wait for a response from the receiver,
entering verify acknowledge state (see 5.2.2). It is highly recommended to
clear the receiving buffer before entering an enquire state, so discarding
any accidental data previously received in the serial communication's receive
buffer, especially in cases where serial communication is interrupt driven.

  Some synchronization needs may also require that before sending the ENQ code,
hosts should send the CAN (cancel) [CC1] control code to force device entering
the 'idle' state.



*******************************************************************************
5.2.2. States definition -> Verify acknowledge
*******************************************************************************
  The verify acknowledge state is the reception of a response code which 
indicates that an action from one side has been accepted by the other. For this
to work, the ascii control codes ACK and NAK [CC1] are used to map positive 
or negative acknowledgement respectively. In this state the sender or the
receiver enters in the following cases:

  - after an enquire state by the sender
  - after a request packet transmittion by the sender
  - after a reply packet transmittion by the receiver

  In any of the above cases, the side which is in the verify acknowledge state
must either accept ACK or NAK as valid responses within a specific time 
window. Any other received control values should be treated as NAK. 

  On reception of an ACK, the host must leave the verify acknowledge state 
and proceed to the next state, if any. This means that the previous state was 
successfuly processed by the other side of the communication. On reception of
a NAK, the host must leave the verify acknowlege state and repeat once more
the previous state. For example, if the verify acknowledge state was for a 
previous enquire state, the enquire state must be repeated. If the request 
packet was not acknowledged, the packet must be retransmitted. 

  To prevent infinite communication loops, each of these cases mentioned are
limited to a specific retransmittion count, which, when reached, indicates 
that the communication attempt causing the retransmittions was unsuccessful
and further communication is not possible for some reason. The possible reasons
for such a failure may be:

  - Disconnection of serial cable
  - Host computer or device fatal error
  - Too noisy communication line




*******************************************************************************
5.2.3. States definition -> Acknowledge state
*******************************************************************************
  The acknowledge state is the transmittion of either ACK or NAK control codes
after a previous enquire or packet reception. ACK must be transmitted when the
enquire is accepted or the packet is verified successfuly. This is 'positive
acknowledge'. NAK must be transmitted when the enquire must be either delayed 
or rejected, or if the packet failed checksum verification. This is 'negative 
acknowledge'. Hosts must not transmit any other codes except ACK, NAK and CAN
in this state. 



*******************************************************************************
5.2.4. States definition -> Packet transmittion state
*******************************************************************************
  This state is the transmittion of either a request or a reply packet by the
sender and the receiver respectively. Packets in both cases follow
the rules described in a later paragraph [see 5.3]. On completion of the
packet transmittion, the sender or receiver advances to the next state, if 
any. During the packet transmittion state, the sender or receiver may also
transmit control codes which will be transparent for the packet data, ie
they will not be included in the data section of the packet.



*******************************************************************************
5.2.5. States definition -> Packet reception state
*******************************************************************************
  The packet reception state is the process of receiving a request or reply
packet. The sender will enter this state when receiving a reply packet and the
receiver when receiving a request packet. Packet reception is initiated with
the reception of the STX control code [CC1]. Any reception of data before the
reception of STX must be silently discarded. Packet reception is terminated
with the reception of ETX control code [CC1]. Any data after the termination
code (ETX) do not belong to this state. See next paragraph for packet handling
and structure. 



*******************************************************************************
5.3. Packet purpose and structure
*******************************************************************************
  The actual communication data are encapsulated in a 'packet'. As described 
above, there are request packets and reply packets. In simple words, request 
packets contain instructions that sender (host) wishes the receiver (device) 
to follow. Reply packets are information which describe how receiver followed 
the instructions and other optional returned information.

  Request packets are always sent by the sender. Reply packets are always sent
by the receiver. Request and reply packets have the same basic structure but 
differ in their contents. 

The packet structure is the following:

                      +-----+--------- - - -+-----+
                      | STX |      Data     | ETX |
                      +-----+--------- - - -+-----+

  Notice that the actual data is between STX and ETX fields which are simply 
the ascii control codes STX and ETX [CC1]. By ASCII definition, the STX/ETX 
control codes indicate the start of text data transmittion and the end of text
data transmittion respectively. Any valid octet between the STX and ETX is 
considered 'data' octet. Valid data octets must be between values '32' and 
'255' (decimal). Octets lower than '32' are considered 'control' codes [1] and
MUST be interpreted specialy. Valid data octets are forming the complete data 
section. Control codes are NOT part of the data and this also applies for the 
STX/ETX control codes. 

  The length of the data section is variable, due to it's multifunctioning 
purpose. device is able to accept data up to 250 octets of data in a single
packet. Hosts MUST be able to accept at least the same amount of data in a 
single packet. The device will discard any further data if this limit is 
reached producing a negative acknoledge to the host. 

  Inside the data section of a packet, request or reply, are 'data fields': 

             <--------------------- Data ------------------->
             +---------+---------+---------+-- - -+---------+
             | Field 1 / Field 2 / Field 3 / .... / Field N |
             +---------+---------+---------+-- - -+---------+

  Data fields form the total of the data section of a packet. Each field's size
may vary. For this reason, a 'special' data character is defined to function as
'field separator'. In both protocol layers, the field separator character is
the slash '/' (ascii character 47 decimal, 057 octal, 2F hexadecimal). The 
Device interprets this character as 'end of current field'. Host application 
has to do the same. As a result of this character's special meaning, hosts 
MUST NOT include this character as part of field data but only as field 
separator. The reason for this is that the device will incorrectly treat it as 
field separator and count one extra field in the packet, probably also shifting 
all other fields by one position to the right. 

  Fields vary in size and content. Various types of fields are described in a 
later paragraph in detail.




*******************************************************************************
5.3.1. Packet verification - error detection
*******************************************************************************
  To ensure that a request or reply packet was received with no errors, both 
layers use a special field: the checksum. Checksum is always the last field in 
the packet in all cases of packet transmittions. It also must be separated 
from the previous field using the slash (/). Checksums are always a 2-digit
decimal values and represent the modulo 100 of the 8-bit sum of all data octets
in the packet except any control codes or the 2-digits checksum itself but 
including the field separators. All field separators are calculated in the
checksum. 

  Example checksum calculation function in 'C':
        +--------------------------------------------------------+
        | BYTE CalcChecksum(BYTE *packet)                        |
        | {                                                      |
        |   BYTE sum = 0;                                        |
        |   int  checklength = strlen(packet) - 2;               |
        |                                                        |
        |   while(checklength--) sum += (BYTE) (*packet++);      |
        |   return( (sum % 100) );                               |
        | }                                                      |
        +--------------------------------------------------------+

  Example checksum calculation function in pseudocode:

        +-------------------------------------------------------------------+
        | Function Calculate_Checksum( parameter data_packet ) Returns BYTE |
        | Begin                                                             |
        |   Declare CALCSUM, I as BYTE                                      |
        |   CALCSUM = 0                                                     |
        |   For I = 0 to stringlength( data_packet ) - 2 Do                 |
        |     CALCSUM  =  CALCSUM + ascii( data_packet[ I ] ) )             |
        |   Next  I                                                         |
        |   CALCSUM = CALCSUM mod 100                                       |
        |   Return CALCSUM                                                  |
        | End                                                               |
        +-------------------------------------------------------------------+

  The receiver of the packet must calculate this checksum localy, compare it
with the transmitter's checksum and, if found equal, the packet is valid and a
positive acknowledgement must be sent. Otherwise the packet was corrupted and a
negative acknowledgement must be sent. The checksum will always be a numeric, 
2-digit field in range 00-99. 

     <---------------------  Data section ------------------->
     <-------------- Layer fields -----------><-- Checksum -->
     +---------+---------+---------+---------+---------------+
     | Field 1 / Field 2 / Field 3 /  . . .  /       CC      |
     +---------+---------+---------+--- - - -+---------------+

  Remembering the state paragraphs above, negative acknowledgements in packet
receptions cause retransmittions of the packet. The scheme that follows 
describes one such case where the packet failed checksum verification twice
and succeeded in the third:

             Sender                        Receiver
        ---------------------------------------------------
               IDLE                        IDLE
            ENQUIRE ---------------------> 
                    <--------------------- ACKNOWLEDGE
             PACKET ---------------------> (verify error)
                    <--------------------- NOT ACKNOWLEDGE
             PACKET ---------------------> (verify error)
                    <--------------------- NOT ACKNOWLEDGE
             PACKET ---------------------> (verify success)
                    <--------------------- ACKNOWLEDGE
             .
             .
             (Rest of packet exchange)
        ---------------------------------------------------




*******************************************************************************
5.3.2. Fields - discussion
*******************************************************************************
  As already mentioned, fields are the building blocks of data packets. In this
paragraph we will examine all available types of fields and their basic 
restrictions and requirements. 
 
  There are only two classes of fields: the string class and the numeric class. 
Further 'type' labeling was necessary to be defined in order to document each 
type's ranges and restrictions. Understanding those is essential because when 
out of 'type' range fields are sent will be rejected by the device on further 
packet processing.

  Although fields of certain class and type have a range, the specific packet 
*may* require a lower range for successful process. Keeping this in mind, 
applying fields to a packet should be done following this scheme:

   - Apply class restrictions checks
   - Apply type restrictions and range checks
   - Apply packet's specification for fields restrictions and range



*******************************************************************************
5.3.3. Fields - Classes
*******************************************************************************
  As mentioned, field classes are either string or numeric. These are the 
attributes of each class.

  String class:

    - Can contain any character of value 32 to 255 (decimal) except slash ('/')
    - Can be of zero to any length that does not exceed the maximum packet size

  Numeric class:
  
    - Can contain any numeric character
    - Can contain a decimal point (.)
    - Can contain a minus as a first character
    


*******************************************************************************
5.3.4. Fields - types in detail
*******************************************************************************
  Field types are used as a method of generating or recognizing specific or 
generic fields for a use in a packet. The list that follows defines the ranges
and restrictions of the specific types.

    ===== INTEGER type ===========================
    Class:              Numeric
    Value range:        '-999999' to '999999'
    Digit range:        1 to 6 digits
    Notes:              Fields of this type must not contain any decimal part
                        or decimal point. This type is usualy used as a counter
                        field or an index.

    ====== DATE6 type =============================
    Class:              Numeric
    Value range:        '010199' to '311240'
    Digit range:        When required, must be 6 digits
                        When optional, may not be sent at all
    Notes:              Specifies a date. Date format is DDMMYY.

    ====== DATE8 type =============================
    Class:              Numeric
    Value range:        '01011999' to '31122040'
    Digit range:        When required, must be 8 digits
                        When optional, may not be sent at all
    Notes:              Specifies a date. Date format is DDMMYYYY.


    ====== TIME type =============================
    Class:              Numeric
    Value range:        '000000' to '235959'
    Digit range:        When required, must be 6 digits
                        When optional, may not be sent at all
    Notes:              Specifies a time. Time format is HHMMSS.

    ====== FLAGS type ============================
    Class:              Numeric
    Value range:        '0' to '1' for each flag in field
    Digit range:        When required, must be as long as the packet
                        requires. When optional, may not be sent at all
    Notes:              Flags type is used to minimize packet fields
                        where a single "true"/"false" or "yes"/"no"
                        type of information must be passed for various
                        attributes.

    ====== STRING type ===========================
    Class:              String
    Value range:        -
    Character range:    1 to 240 (if not exceeding max packet size)
    Notes:              A generic string type, usefull for various non
                        numerical cases.



*******************************************************************************
5.4. Request/Reply packets - Further discussion
*******************************************************************************
  To have a closer look to the structure of request and reply packets:

  Request packet:  
  <---------------------------------- Data --------------------------------->
                  <------------- Optional Section -------------->
  +--------------++---------------------------------------------++----------+
  | Request code || Field 1 / Field 2 / Field 3 / ... / Field N || Checksum |
  +--------------++---------------------------------------------++----------+
  
  The first field in the request packet is called 'request code'. The request
  code is always a simple STRING field of one character fixed length.
  
  Reply packet:    
  <---------------------------------- Data ------------------------------->
                                  <----- Optional Section ---->
  +------------+--------+--------++---------------------------++----------+
  | Reply code | Stat-1 | Stat-2 || Field1/Field2/.../FieldN  || Checksum |
  +------------+--------+--------++---------------------------++----------+

  In request packets, the request data are not always required (notice that 
'request data' are inside <>). In the same manner, reply packets may not always
have reply data. All other sections are always present.

  'Reply code' is a single numeric field of 2 hexadecimal digits identifying
the result of the command execution by the device. A zero reply code ('00') 
indicates that the command executed successfuly. A non zero reply code indicates
an error in command execution. Error codes returned are explained in detail in
a later section. Receiving a non zero reply code means that the command was NOT
executed. Receiving a zero reply code means that the command has been or will be
successfuly executed. Commands that require very little time to execute, such as
information retrieve, will be executed before the reply packet is transmitted. 
This is because the reply packet data fields depend on the command execution 
itself. Commands that take long time to execute, such as report issuing, will be
only checked, a reply packet will be sent, and then will be executed. 

  'Stat-1' Is also a single numeric field of 2 hexadecimal digits. It's binary
value maps to several device 'flags' which inform the host application of some 
hardware related events of the device. In detail:

  +--------+--------+--------+--------+--------+--------+--------+--------+
  | Bit 7  | Bit 6  | Bit 5  | Bit 4  | Bit 3  | Bit 2  | Bit 1  | Bit 0  |
  +--------+--------+--------+--------+--------+--------+--------+--------+
  |  BATOK | FCONN  |  USER  | PCONN  |  CMOS  | PP.END | FATAL  | BUSY   |
  +--------+--------+--------+--------+--------+--------+--------+--------+
  
Bit 0:  Device busy
        This bit when set to '1' indicates that the device is currently busy
        executing a previous command or other task. When busy, the device may
        execute some non critical commands and refuse to execute others 
        replying an error 'Device busy - Unable to execute' (See error codes).
        The host must check this bit (requesting a 'status') before issuing
        any critical commands, or, must keep sending the command until the
        command is executed (or failed by other reason). BUSY state is a 
        temporary state but, due to very different tasks the device may
        cause the BUSY state, the time which the BUSY flag will be found set
        is varying from a few milliseconds to few minutes. A host may 
        inform the user after (for example) one minute, that the device is
        busy in other task and ask for a 'retry' or 'cancel' of the requested
        operation. An example in which a BUSY flag will be set for long time
        is a fiscal report issuing: When the host (or the device user)
        requests a fiscal report with many records, the report will take long
        time to finish, thus keeping the BUSY flag set for long. It is 
        highly recommended though that a host should NOT produce a 'device
        busy' error message to the application user before (at least) ten
        (10) seconds. It is also recommended that the host application must 
        allow the user to cancel or retry the operation.
Bit 1:  Fatal error
        This bit indicates that (when set to one) the device detected a fatal
        hardware related error and cannot process most of the commands. Fatal 
        errors may be a bad fiscal unit, a RAM integrity error or others. From
        application point of view, this bit means that other critical commands 
        should not be sent, and a service to the device is required. 
Bit 2:  Printer Paper End
        This bit indicates (when set to one) that the printer is out of paper,
        and must be replaced before the previous task completed its printing
        duty. Usualy, when this flag is set, the 'device busy' flag may be set
        also, if a previous command that used the printer caused the paper end
        error. So, it is recommended that the paper end bit MUST be checked 
        before the busy bit. Host application may inform the user of the need
        to insert new role of paper to the printing mechanism. After doing so,
        this bit will be cleared and the command (that detected the paper end)
        may be retransmitted normaly.
Bit 3:  CMOS reset indication
        This bit indicates (when set) that the device has perform a CMOS reset
        (complete clearing of its system memory). When the host application 
        finds this bit set, a user warning must be issued, in order to start
        a recovery procedure.
Bit 4:  Printer online
        This bit indicates (when zero) that the printing device is not 
        responding to printing commands. Recommended action is to power off
        the printer and on again and retry the command. If the problem persists,
        the device needs to be serviced. 
Bit 5:  User operation in progress
        This bit indicates that the device is currently being used through its
        keyboard driven menu system by the operator. This causes a BUSY state,
        in which no command execution is allowed through the protocol mechanism
        until the operator finishes browsing the device. Any command transmit-
        tion will fail with error code 0x17 (see error codes). Applications 
        should either tolerate this delay indefinitely or inform user about 
        this situation after a while. 
Bit 6:  Fiscal unit online
        This bit indicates (when zero) that a fiscal physical unit is not
        responding to commands. Because this is a critical error, bit 1 may be
        also set. Device may need to be serviced.
Bit 7:  Battery Good
        This bit indicates (when set) that the board's battery is in good 
        condition. If this bit is zero, commands may return error.

Example:Assume device status field is '41'. This hexadecimal value, when 
        converted to binary will be '01000001'. The '1's mean that the fiscal 
        unit is online (bit 6) and the device is busy (bit 0).

'Stat-2' Is also a single numeric field of 2 hexadecimal digits. It's binary
value maps to several 'flags' which inform the host application of the current
application state of the device. In detail:

  +--------+--------+--------+--------+--------+--------+--------+--------+
  | Bit 7  | Bit 6  | Bit 5  | Bit 4  | Bit 3  | Bit 2  | Bit 1  | Bit 0  |
  +--------+--------+--------+--------+--------+--------+--------+--------+
  | FFULL  | DFULL  | FWARN  |   --   |  RCVR  |  SIP   |  DAY   |   --   |
  +--------+--------+--------+--------+--------+--------+--------+--------+

Bit 0:  (Reserved, set to zero)
Bit 1:  This flag indicates that there is an open day in the device. This 
        means that one or more signatures or reports have been issued after 
        a daily closure report. The day open flag will be zero after the 
        issuing of a Z report and before issuing anything else, reports or 
        signatures. A 'day' is defined in as the period between two Z 
        closures.
Bit 2:  Signature In Progress
        This flag is indicating that a signature is currently in 'open' state
        in the device. An application can prevent errors in commands by 
        detecting this bit. For example, a command 'issue Z report' will fail
        if this bit is set. This bit is set upon reception of an 'open 
        signature block' command. It is cleared after a block termination or
        cancelation. 
Bit 3:  Recover in progress
        This flag indicates (when set) that the host application has initiated
        a daily signature list recover procedure. This flag is set by the 
        device upon reception of the first 'open signature block' command in
        'recovery' mode. It is cleared after a Z closure report.
Bit 4:  (Reserved, set to zero)
Bit 5:  Fiscal warning indicator
        This bit becomes set when the firmware detects that the fiscal unit
        has no more than 50 records remaining capacity. This may serve as a 
        warning to the host application; the user should be informed as soon
        as possible. When this bit is initialy set, it will remain set all
        the way to the remaining 50 records. Also, the Z closures will have
        a fiscal warning line printed. The host must treat this information
        as a warning condition rather than an error condition.
Bit 6:  This bit indicates that the device has reached the maximum number of 
        signatures that can hold for a single day. Having this bit set, all
        signature issuing commands will fail with error code 0x18 (see error 
        codes). To resolve this, the host must issue a z closure to clear the
        day and continue normally.
Bit 7:  This flag indicates that the fiscal file used to store daily data after
        a 'Z' closure report is now full. When this happens, the device is
        unable to issue signatures, reports of any kind except the fiscal 
        periodical report. 
Example:Assume fiscal status field is '06'. This hexadecimal value, when 
        converted to binary will be '00000110'. The '1's mean that the device
        has a day in open state (bit 1) and a signature is currently being 
        generated (bit 2).




*******************************************************************************
6. Packet groups
*******************************************************************************

  Packets, grouped, are:

  - Setup updating and reading commands
    * Program Header
    * Program Real-Time Clock/Calendar
    * Read Real-Time Clock/Calendar
    * Read Device ID/S-N
  - I/O device and status related commands
    * Display message
    * Version number
    * Device status
  - Signature related commands
    * Begin signature block
    * Sign block
    * Sign text block 
    * End signature block 
    * Abort signature block
    * Read signature entry 
    * Summary status info
    * Read closure data
  - Report issuing commands
    * Print closure report
    * Print fiscal report (date to date)
    * Print fiscal report (Z to Z)
    
    
*******************************************************************************
6.1. Packets in detail -> Program header [H]
*******************************************************************************

  Programs the header in the device. The header is stored in the fiscal 
memory. Lines that will not be passed in the command will not be printed. 
To program a blank line, the host must pass the line filled with spaces. 
The lines provided for header will NOT be centered automatically.

Request packet:
***************
Request code:           'H'
Total field count:      14 (Counting request code & checksum fields)
Example request:        "H/0/HEADER LINE 1/0/HEADER LINE 2/
                           0/HEADER LINE 3/0/HEADER LINE 4/
                           0/HEADER LINE 5/0/HEADER LINE 6/68" (checksum hypothetical)
==== Field 1:             Request code 'H' (as described)
==== Field 2,4,6,8,10,12: Header line printing types
Type:                     INTEGER
Length:                   1
Notes:                    The printing type for each header line as:
                          1 = Normal printing, 2 = Double height
                          3 = Double width,    4 = Double width/height
                          When printing double width, only 16 
                          characters of the line can be printed.
==== Field 3,5,7,9,11,13: Header line text
Type:                     STRING
Length:                   0-32 characters
Notes:                    The text data for each line
==== Field 14:            Checksum (as described)

Reply packet: 
*************
Total field count:      4 (Counting reply code, status1,2 & checksum)
Example reply packet:   "00/01/02/63" (status1,2 & checksum are hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum 



*******************************************************************************
6.1a. Packets in detail -> Read header [h]
*******************************************************************************

  Reads the current (active) header setting in the device. Also returns the 
times that this header is programmed and the times that are remaining for 
reprogramming.

Request packet:
***************
Request code:             'h'
Total field count:        2 (Counting request code & checksum fields)
Example request:          "h/04" (checksum hypothetical)
==== Field 1:             Request code 'h' (as described)
==== Field 2:             Checksum 

Reply packet: 
*************
Total field count:      18 (Counting reply code, status1,2 & checksum)
Example reply packet:   "00/01/02/0/HEADER LINE 1/0/HEADER LINE 2/
                         0/HEADER LINE 3/0/HEADER LINE 4/
                         0/HEADER LINE 5/0/HEADER LINE 6/
                         3/7/51" (status1,2 & checksum are hypothetical)

==== Field 1:             Reply code
==== Field 2:             Status 1
==== Field 3:             Status 2
==== Field 4,6,8,10,12,14:Header line printing types
Type:                     INTEGER
Length:                   1
Notes:                    The printing type for each header line as:
                          1 = Normal printing, 2 = Double height
                          3 = Double width,    4 = Double width/height
==== Field 5,7,9,11,13,15:Header line text
Type:                     STRING
Length:                   0-32 characters
Notes:                    The text data for each line

==== Field 16:            Count of header records written
Type:                     INTEGER
Length:                   1-2
Notes:                    The number of times the title is programmed in 
                          fiscal memory.
==== Field 17:            Count of header records remaining
Type:                     INTEGER
Length:                   1-2
Notes:                    The number of times the title remains to be 
                          programmed.
==== Field 18:            Checksum



*******************************************************************************
6.2. Packets in detail -> Program the Real-Time Clock/Calendar [T]
*******************************************************************************

  This command is used to program the device's real time clock (ie: time and
date). For this command to succeed, the 'clock' jumper must be short, otherwise
the command will fail. Also, the date must not be prior to the last fiscal 
record's date. 

Request packet:
***************
Request code:           'T'
Total field count:      4 (Counting request code & checksum fields)
Example request:        "T/131200/204200/83" (checksum hypothetical)
==== Field 1:           Request code 'T'
==== Field 2:           System date
Type:                   DATE6
Length:                 Default (fixed 6)
Notes:                  The date to set in RTC (Real time clock)
==== Field 3:           System time
Type:                   TIME (fixed 6)
Length:                 Default
Notes:                  The time to set in RTC 
==== Field 4:           Checksum (as described)

Reply packet:
*************
Total field count:      4 (Counting reply code, status1,2 & checksum)
Example reply packet:   "00/01/02/63" (status1,2 & checksum are hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum 


*******************************************************************************
6.3. Packets in detail -> Read the Real-Time Clock/Calendar [t]
*******************************************************************************

  This command is used to read the device's real time clock.

Request packet:
***************
Request code:           't'
Total field count:      2 (Counting request code & checksum fields)
Example request:        "t/56" (checksum hypothetical)
==== Field 1:           Request code 't'
==== Field 2:           Checksum

Reply packet:
*************
Total field count:      6 (Counting reply code, status & checksum)
Example reply:          "00/00/00/210300/174345/56" 
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           System date
Type:                   DATE6
Length:                 Fixed, 6 digits
Notes:                  The current date in device
==== Field 5:           System time
Type:                   TIME
Length:                 Fixed, 6 digits
Notes:                  The current time in device
==== Field 6:           Checksum





*******************************************************************************
6.4. Packets in detail -> Read Device ID/S-N [a]
*******************************************************************************

  This command is used to read the device's serial number

Request packet:
***************
Request code:           'a'
Total field count:      2 (Counting request code & checksum fields)
Example request:        "a/86" (checksum hypothetical)
==== Field 1:           Request code 'a'
==== Field 2:           Checksum

Reply packet:
*************
Total field count:      5 (Counting reply code, status & checksum)
Example reply:          "00/00/00/ABC02001234/96"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Device serial number 
Type:                   STRING
Length:                 Fixed, 11 digits (3 letters, 8 digits)
Notes:                  The device's unique serial number
==== Field 5:           Checksum




*******************************************************************************
6.5. Packets in detail -> Display message [7]
*******************************************************************************

  This command is used to show a message to display unit.

Request packet:
***************
Request code:           '7'
Total field count:      3 (Counting request code & checksum fields)
Example request:        "7/1/TEST MESSAGE/36" (checksum hypothetical)
==== Field 1:           Request code '7'
==== Field 2:           Line number
Type:                   INTEGER
Length:                 Fixed, 1 digit (0-2)
Notes:                  The display line to show the message. If zero, the
                        the display is cleared and the message in field 3 is 
                        ignored. Otherwise, it can be either 1 or 2 specifying
                        the line.
==== Field 3:           Message
Type:                   STRING
Length:                 1 to 20 characters
Notes:                  The text shown is limited by the display width, which 
                        may vary depending on model. The safest text size 
                        though is 16 characters, because it is guaranteed that
                        all compatible models will support it.
==== Field 4:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/96"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum




*******************************************************************************
6.6. Packets in detail -> Read Version [v]
*******************************************************************************

  The read version command in usefull for retrieving the protocol version. See
also paragraph [3] for version compatibility issues. 

Request packet:
***************
Total field count:      2 (Counting request code & checksum fields)
Example request:        "v/51" (checksum hypothetical)
==== Field 1:           Request code 'v'
==== Field 2:           Checksum

Reply packet:
*************
Total field count:      7 (Counting reply code, status & checksum)
Example reply:          "00/00/00/MICRELEC/MODEL/02.24/17"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Vendor information
Type:                   STRING
Length:                 Variable, 1-40
Notes:                  A vendor information string.
==== Field 5:           Model information
Type:                   STRING
Length:                 Variable, 1-40
Notes:                  A model information string. This can be usefull in
                        determining specific physical information about the
                        device (ie display width, max signatures in day etc).
==== Field 6:           Version
Type:                   STRING
Length:                 Fixed, 5 characters
Notes:                  Contain the protocol version in form XX.YY where XX is
                        the major number and YY is the minor number.
==== Field 7:           Checksum



*******************************************************************************
6.7. Packets in detail -> Read Device Status [?]
*******************************************************************************

  This command has no additional input output data. It is only used for getting
the status codes from the device. Otherwise it is a NOOP (no operation).

Request packet:
***************
Request code:           '?'
Total field count:      2 (Counting request code & checksum fields)
Example request:        "?/36" (checksum hypothetical)
==== Field 1:           Request code '?'
==== Field 2:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/96"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum




*******************************************************************************
6.8. Packets in detail -> Begin signature block [{]
*******************************************************************************

  This command initiates a new signature context. It must be sent by the host
before any 'sign block' commands. For the successful completion, there must not
be an already open block in progress. To determine this, the host can examine
the 'status-2' SIP (Signature in progress) bit. Additionally, this command may
fail if the maximum number of signatures is already stored in daily signature 
memory of the device. If this happens, then a Z closure will free the memory
and the application may continue to issue signatures. Another possible reason
of failure may be when 24 hours have passed from the last closure (Z) report
issued by the device. Also in this case a Z closure will terminate this 
condition. 
  When specifing a memory recover (field 2 set to '1'), means that the host is
initiating (or continuing) a memory recover procedure. This procedure is the 
process of regenerating *all* signatures lost due to a device's CMOS memory 
reset. 

Note1: An application opening a new block should never delay sending the 'sign 
       block' / 'sign text block' commands. To be more specific, after opening
       the block, the host *must* issue commands in no more than ten seconds. 
       Failing to do so, the device will automatically terminate the block and
       will abort the currenly generated signature, increasing the number of 
       'communication down' events that is printed in Z closures and saved in
       fiscal memory. 

Note2: A power loss when a block is open in the device, causes the automatic 
       cancelation of the block at the next power up. This event is counted,
       printed at the next Z closure and saved in the fiscal memory.

Note3: On command success: if the memory recover flag is set to '0', the SIP 
       and DAY bits of 'status-2' are also set. Otherwise if the memory recover
       flag is '1', the SIP, DAY and RCVR flags are set.
       

Request packet:
***************
Request code:           '{'
Total field count:      3 (Counting request code & checksum fields)
Example request:        "{/0/78" (checksum hypothetical)
==== Field 1:           Request code '{'
==== Field 2:           Memory recover flag
Type:                   INTEGER
Length:                 Fixed, 1 digit (0-1)
Notes:                  When this field is '0' a normal signature block is 
                        created. When set to '1', indicates that the host is
                        initiating or continuing a memory recover operation.
==== Field 3:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/96"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum




*******************************************************************************
6.9. Packets in detail -> Sign block [*]
*******************************************************************************

  This is the command for sending data for signing to the device. To succeed, 
the device must have a signature block in progress (see status-2, SIP bit and 
paragraph 6.8) otherwise an error will be returned and the data will not be 
signed. On success, the current open block size will be increased by the
length of the binary data passed.

Note: The hexadecimal format is required because it provides the host the means
      to transmit control codes along with the printable ascii characters. If
      the signing stream is all pure printable text (ie greater or equal to 
      whitespace ' ' in ascii code) then the application can issue the 'sign
      text block' instead, which have less communication overhead. In all other
      cases (ie when the stream to be signed contain control codes, CR/LF, 
      TABs, etc) the host application *must* use this command.

Note: To achieve the less possible communication overhead, the host application
      is strongly recommended to use the maximum block size whenever possible.
      For example, to sign a stream of 1000 bytes, it is faster to issue the
      'sign block' command two times with 500 bytes each time than to issue the
      'sign block' command four times with 250 bytes each time. This guarantees 
      the maximum delivered sign rate. 

Request packet:
***************
Request code:           '*'
Total field count:      3 (Counting request code & checksum fields)
Example request:        "*/A1C03486D2C7A5810DC2/78" (checksum hypothetical)
==== Field 1:           Request code '*'
==== Field 2:           Data block to be signed
Type:                   STRING
Length:                 2-1000 (Always even sized)
Notes:                  This is the data block in HEX encoded form. This block
                        can be constructed by the host application by convert-
                        ing all bytes in the data stream to ascii HEX pairs. 
                        Example: The stream "abcdefghijklmnop" will become:
                        "6162636465666768696A6B6C6D6E6F70". 
==== Field 3:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/96"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum

*******************************************************************************
6.9a. Packets in detail -> Sign text block [@]
*******************************************************************************

  This is the command for sending pure text data for signing to the device. To
succeed, the device must have a signature block in progress (see status-2, SIP 
bit, and paragraph 6.8) otherwise an error will be returned and the data will 
not be signed. On success the current open block size will be increased by the
length of the text data passed.

Note: This command is used for printable text data *only* (ie: characters that
      are greater or equal to whitespace in ascii code representation).

Note: To achieve the less possible communication overhead, the host application
      is strongly recommended to use the maximum text size whenever possible.
      For example, to sign a text block of 2000 characters, it is faster to 
      issue the 'sign text block' command two times with 1000 characters each 
      time, than to issue the command four times with 500 characters each time.
      This guarantees the maximum delivered sign rate.

Request packet:
***************
Request code:           '@'
Total field count:      3 (Counting request code & checksum fields)
Example request:        "@/Text to be signed here/78" (checksum hypothetical)
==== Field 1:           Request code '@'
==== Field 2:           Text to be signed
Type:                   STRING
Length:                 2-1000
Notes:                  This is the text data 
==== Field 3:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/96"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum

*******************************************************************************
6.9b. Packets in detail -> Sign BASE64 encoded block [&]
*******************************************************************************
  
  This is the command for sending BASE64 encoded data for signing to the 
device. To succeed, the device must have a signature block in progress (see 
status-2, SIP bit, and paragraph 6.8) otherwise an error will be returned and 
the data will not be signed. On success the current open block size will be 
increased by the length of the BASE64 decoded data passed.

Note: The data stream passed to this command *must* conform with the 
      requirements of BASE64 encoding, otherwise an error 0x05 (Field range or 
      type check failed) will be returned. 

Request packet:
***************
Request code:           '&'
Total field count:      3 (Counting request code & checksum fields)
Example request:        "&/aB0c2wWx3qaLd8gB/50" (checksum hypothetical)
==== Field 1:           Request code '&'
==== Field 2:           BASE64 encoded data to be signed
Type:                   STRING
Length:                 4-1000 (always a multiple of 4 in base64 encoding)
Notes:                  This is the base64 encoded data field
==== Field 3:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/96"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum


*******************************************************************************
6.10. Packets in detail -> End of signature block [}]
*******************************************************************************

  This is the command for terminating the current block and receiving the final
signature for this block. The device will issue a digital signature receipt 
which states the fact that this signature is stored into the device's signature
memory. The returned signature must be used by the host application to validate
the printed document. The daily count of signatures issued and the progressive 
total count of signatures are increased by one. 

Note1:  If the application for any reason lost the information returned by this
        command, the 'read signature entry' command must be used to retrieve
        the last signature issued (see 6.11). 

Request packet:
***************
Request code:           '}'
Total field count:      2 (Counting request code & checksum fields)
Example request:        "}/61" (checksum hypothetical)
==== Field 1:           Request code '}'
==== Field 2:           Checksum

Reply packet:
*************
Total field count:      11 (Counting reply code, status & checksum)
Example reply:          "00/00/00/123/123/220402/134124
                         /0102030405060708091011121314151617181920
                         ABC02000001/1221/26"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Signature's total progressive number
Type:                   INTEGER
Length:                 Default
Notes:                  It is the total progressive signature number
==== Field 5:           Daily signature number
Type:                   INTEGER
Length:                 Default
Notes:                  It is the daily progressive number of this signature.
==== Field 6:           Issuing date of signature
Type:                   DATE6
Length:                 Default
==== Field 7:           Issuing time of signature
Type:                   TIME
Length:                 Default
==== Field 8:           Signature
Type:                   STRING
Length:                 40 characters fixed
Notes:                  It is the calculated signature of the passed data block
                        It is in form of 20 hex pairs.
==== Field 9:           Device serial number 
Type:                   STRING
Length:                 Fixed, 11 digits (3 letters, 8 digits)
Notes:                  The device's unique serial number
==== Field 10:          Next Z number
Type:                   INTEGER
Length:                 1-4
Notes:                  The next Z number that will be issued.
==== Field 11:          Checksum

*******************************************************************************
6.10a. Packets in detail -> Abort signature block [^]
*******************************************************************************

  This command is used for aborting a currently open signature block. The 
reason for the host application to use this command, is in cases when a fatal
application error requires the premature termination of the program, or in
cases when the operating system forces the program to early termination for 
reasons concerning possible critical tasks (for example, power down). In such
cases, the application is not able to complete the signature data, but leaving
the block open will lead to 'host diconnections' in the device side after a
while. So aborting the block is the best way to avoid those events in such 
conditions. 

Request packet:
***************
Request code:           '^'
Total field count:      2 (Counting request code & checksum fields)
Example request:        "^/61" (checksum hypothetical)
==== Field 1:           Request code '^'
==== Field 2:           Checksum

Reply packet:
*************
Total field count:      11 (Counting reply code, status & checksum)
Example reply:          "00/00/00/123/123/220402/134124
                         /0102030405060708091011121314151617181920
                         ABC02000001/132/98"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Aborted signature's total progressive number
Type:                   INTEGER
Length:                 Default
Notes:                  It is the total progressive signature number that the 
                        signature would have if it was not aborted.
==== Field 5:           Daily signature number
Type:                   INTEGER
Length:                 Default
Notes:                  It is the daily progressive number that this signature
                        would have if it was not aborted.
==== Field 6:           Date of aborted signature 
Type:                   DATE6
Length:                 Default
==== Field 7:           Time of aborted signature
Type:                   TIME
Length:                 Default
==== Field 8:           Aborted signature data
Type:                   STRING
Length:                 40 characters fixed
Notes:                  It is the calculated signature of the aborted data block
                        It is in form of 20 hex pairs.
==== Field 9:           Device serial number 
Type:                   STRING
Length:                 Fixed, 11 digits (3 letters, 8 digits)
Notes:                  The device's unique serial number
==== Field 10:          Next Z number
Type:                   INTEGER
Length:                 1-4
Notes:                  The next Z number that will be issued.
==== Field 11:          Checksum


*******************************************************************************
6.11. Packets in detail -> Read signature entry [$]
*******************************************************************************

  This command is usefull for retrieving the device's last issued signature
(or any signature existing in the day) when for any reason the host application
has lost this information (for example, the host aquired a signature but before
processing it, the power went down). In this way it is not needed to issue a 
new signature; this command returns the exact data returned as the 'end of 
signature block' command. The requirement of this command is that a new 
signature must *not* be in progress. 
  
Request packet:
***************
Request code:           '$'
Total field count:      3 (Counting request code & checksum fields)
Example request:        "$/0/42" (checksum hypothetical)
==== Field 1:           Request code '$'
==== Field 2:           Signature Number
Type:                   INTEGER
Length:                 1-4
Notes:                  When non zero, it specifies the daily number of 
                        signature to be retrieved. This implies that the range
                        must be 1 to 'last saved signature no'. If the 
                        requested number does not exist, an error 0x1F will be 
                        returned.
                        When zero, it specifies that the host application is 
                        requesting the last signature saved. If no signature 
                        has been issued in the day (ie: day not yet open) then 
                        an error 0x1F (see error codes) will be returned.
==== Field 3:           Checksum

Reply packet:
*************
Total field count:      11 (Counting reply code, status & checksum)
Example reply:          "00/00/00/123/123/220402/134124
                         /0102030405060708091011121314151617181920
                         /ABC02000001/122/26"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Requested signature's total progressive number
Type:                   INTEGER
Length:                 Default
Notes:                  It is the total progressive number of the requested
                        signature.
==== Field 5:           Daily number of requested signature
Type:                   INTEGER
Length:                 Default
Notes:                  It is the daily progressive number of the requested
                        signature.
==== Field 6:           Issuing date of requested signature
Type:                   DATE6
Length:                 Default
==== Field 7:           Issuing time of requested signature
Type:                   TIME
Length:                 Default
==== Field 8:           Last Signature
Type:                   STRING
Length:                 40 characters fixed
Notes:                  It is the calculated signature of the requested data 
                        block. It is in form of 20 hex pairs.
==== Field 9:           Device serial number 
Type:                   STRING
Length:                 Fixed, 11 digits (3 letters, 8 digits)
Notes:                  The device's unique serial number
==== Field 10:          Closure number  
Type:                   INTEGER
Length:                 Default
Notes:                  The next closure number (Z) that owns the signature.
==== Field 11:          Checksum



*******************************************************************************
6.12a. Packets in detail -> Summary status info [Z]
*******************************************************************************

  This command is used in retrieving various signature generation counters.
For example, when a host application is starting, it should read the device's
last Z closure number. This is done to determine if it is required to 
retrieve any unread Z closure data.

Request packet:
***************
Request code:           'Z'
Total field count:      2 (Counting request code & checksum fields)
Example request:        "Z/70" (checksum hypothetical)
==== Field 1:           Request code 'Z'
==== Field 2:           Checksum

Reply packet:
*************
Total field count:      9 (Counting reply code, status & checksum)
Example reply:          "00/00/00/32/27/32/1002/62"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2

==== Field 4:           Last Z closure number
Type:                   INTEGER
Length:                 1-4
Notes:                  It is the last Z closure number issued.
==== Field 5:           Total progressive number of signatures
Type:                   INTEGER
Length:                 default
Notes:                  It is the total progressive number of the registered
                        signatures.
==== Field 6:           Daily number of signatures 
Type:                   INTEGER
Length:                 Default
Notes:                  It is the daily progressive number of the registered
                        signatures.
==== Field 7:           Current signature block count
Type:                   INTEGER
Length:                 Default
Notes:                  If a signature block is open, this number specifies the
                        amount of data passed. Otherwise (if block not open) it
                        is zero.
==== Field 8:           Remaining daily signatures.
Type:                   INTEGER
Length:                 1-4
Notes:                  The remaining signature capacity before Z clearing is
                        required. Adding this with 'Daily number of signatures'
                        (Field 6) reflects the total day signature capacity. 
==== Field 9:           Checksum


*******************************************************************************
6.12b. Packets in detail -> Read closure data [R]
*******************************************************************************

  This command is used by the host for reading one or more missing Z closure 
records. 

Request packet:
***************
Request code:           'R'
Total field count:      4 (Counting request code & checksum fields)
Example request:        "R/12/72" (checksum hypothetical)
==== Field 1:           Request code 'R'
==== Field 2:           Closure number
Type:                   INTEGER
Length:                 1-4 digits
Notes:                  The Z closure number to request. When set to zero, the
                        command returns the last closure
==== Field 3:           Checksum

Reply packet:
*************
Total field count:      11 (Counting reply code, status & checksum)
Example reply:          "00/00/00/123/123/220402/134124
                         /0102030405060708091011121314151617181920
                         /ABC02000001/26"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Total progressive number of signatures
Type:                   INTEGER
Length:                 Default
Notes:                  It is the total progressive number of signatures up to 
                        the requested closure.
==== Field 5:           Daily total number of signatures
Type:                   INTEGER
Length:                 Default
Notes:                  It is the daily progressive number of the requested
                        signature.
==== Field 6:           Issuing date of requested signature
Type:                   DATE6
Length:                 Default
==== Field 7:           Issuing time of requested signature
Type:                   TIME
Length:                 Default
==== Field 8:           Last Signature
Type:                   STRING
Length:                 40 characters fixed
Notes:                  It is the calculated signature of the requested data 
                        block. It is in form of 20 hex pairs.
==== Field 9:           Device serial number 
Type:                   STRING
Length:                 Fixed, 11 digits (3 letters, 8 digits)
Notes:                  The device's unique serial number
==== Field 10:          Z closure number 
Type:                   INTEGER
Length:                 default
Notes:                  It is the Z closure number (usefull when requesting
                        the last closure '0')
==== Field 11:          Checksum

*******************************************************************************
6.13. Packets in detail -> X/Z report [x]
*******************************************************************************

  This command is for issuing the daily closure (Z) report or the registered
signatures list report. When issuing closure (Z) the error 0x24 (closure date
warning) will be returned if the previous closure was issued at least 48 hours
before the new one. This error is produced to encourage the host to verify the
correct settings of the device's real-time clock. In this case the host may
use value '2' in report selector to override this error and finaly issue the
report. To summarize, the operation may be (in pseudocode): 

   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   Issue 'x/0/0' command (Z report, no list) and read reply
   If received reply code is 0x24 then do:
     Issue 't' command (read real-time clock)
     Check if date/time returned is okay 
     If date/time returned not okay then do:
       Inform user that device's real-time clock is bogus
       and stop all device operations
     Else (date is okay) do:
       Issue 'x/2/0' command (Z report, ignore date check, no list)
     Endif
   Else
     .. (check for other reply values, etc)
   Endif
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Request packet:
***************
Request code:           'x'
Total field count:      4 (Counting request code & checksum fields)
Example request:        "x/1/1/56" (checksum hypothetical)
==== Field 1:           Request code 'x'
==== Field 2:           Report selector
Type:                   INTEGER
Length:                 1 digit fixed (0 or 1)
Notes:                  '0' = Daily closure report (Z)
                        '1' = List of the registered signatures (X)
                        '2' = Daily closure report (Z) with no date warning
==== Field 3:           List flag
Type:                   INTEGER
Length:                 1 digit fixed (0 or 1)
Notes:                  Include a printing of the daily registered signatures
                        in the Z closure report when set to '1'. Note that 
                        this is not required by law to print this list in Z
                        closure; it is optional.
==== Field 3:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/32"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum


*******************************************************************************
6.13a. Packets in detail -> X ranged [X]
*******************************************************************************

  This command is for issuing a list of daily signatures report with capability
of specifying a requested range.

Request packet:
***************
Request code:           'X'
Total field count:      5 (Counting request code & checksum fields)
Example request:        "X/4/12/36" (checksum hypothetical)
==== Field 1:           Request code 'X'
==== Field 2:           Start entry no 
Type:                   INTEGER, range 1-xxxx
Length:                 1-4
Notes:                  The starting entry to print from.
==== Field 3:           End entry no
Type:                   INTEGER, range 1-xxxx
Length:                 1-4
Notes:                  The last entry to print.
==== Field 4:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/32"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum

*******************************************************************************
6.14. Packets in detail -> Fiscal report (date to date) [f]
*******************************************************************************

  This command is for issuing a date to date fiscal report. 

Request packet:
***************
Request code:           'f'
Total field count:      4 (Counting request code & checksum fields)
Example request:        "f/010102/311202/60" (checksum hypothetical)
==== Field 1:           Request code 'f'
==== Field 2:           Start date
Type:                   DATE6
Length:                 Default
Notes:                  The starting date that defines the requesting fiscal 
                        period.
==== Field 3:           End date
Type:                   DATE6
Length:                 Default
Notes:                  The ending date that defines the requesting fiscal 
                        period.
==== Field 4:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/32"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum


*******************************************************************************
6.15. Packets in detail -> Fiscal report (Z to Z) [z]
*******************************************************************************

  This command is for issuing a Z to Z fiscal report. 

Request packet:
***************
Request code:           'z'
Total field count:      4 (Counting request code & checksum fields)
Example request:        "z/1/122/60" (checksum hypothetical)
==== Field 1:           Request code 'z'
==== Field 2:           Start Z number
Type:                   INTEGER
Length:                 1-4
Notes:                  The starting Z number that defines the requesting 
                        fiscal period.
==== Field 3:           End Z number
Type:                   INTEGER 
Length:                 1-4
Notes:                  The ending Z number that defines the requesting fiscal
                        period.
==== Field 4:           Checksum

Reply packet:
*************
Total field count:      4 (Counting reply code, status & checksum)
Example reply:          "00/00/00/32"
                        (reply code, status1,2 & checksum hypothetical)
==== Field 1:           Reply code
==== Field 2:           Status 1
==== Field 3:           Status 2
==== Field 4:           Checksum





*******************************************************************************
7. Tables and miscelaneous definitions
*******************************************************************************


7.1. Table 1, Reply codes / error codes
+---+----------------------------------+----------------------------------------+
|Hex| Meaning                          | Suggested action                       |
+---+----------------------------------+----------------------------------------+
| 00| No errors - success              | None                                   |
| 01| Wrong number of fields           | Check the command's field count        |
| 02| Field too long                   | A field is long: check it & retry      |
| 03| Field too small                  | A field is small: check it & retry     |
| 04| Field fixed size mismatch        | A field size is wrong: check it & retry|
| 05| Field range or type check failed | Check ranges or types in command       |
| 06| Bad request code                 | Correct the request code (unknown)     | 
| 09| Printing type bad                | Correct the specified printing style   |
| 0A| Cannot execute with day open     | Issue a Z report to close the day      |
| 0B| RTC programming requires jumper  | Short the 'clock' jumper and retry     |
| 0C| RTC date or time invalid         | Check the date/time range. Also check  |
|   |                                  | if date is prior to a date of a fiscal |
|   |                                  | record.                                |
| 0D| No records in fiscal period      | No suggested action; the operation can-|
|   |                                  | not be executed in the specified period|
| 0E| Device is busy in another task   | Wait for the device to get ready       |
| 0F| No more header records allowed   | No suggested action; the header pro-   |
|   |                                  | gramming cannot be executed because the|
|   |                                  | fiscal memory cannot hold more records |
| 10| Cannot execute with block open   | The specified command requires no open |
|   |                                  | signature block for proceeding. Close  |
|   |                                  | the block and retry.                   |
| 11| Block not open                   | The specified command requires a signa-|
|   |                                  | ture block to be open to execute. Open |
|   |                                  | a block and retry.                     |
| 12| Bad data stream                  | Means that the passed data to be signed|
|   |                                  | are of incorrect format. The expected  |
|   |                                  | format is in HEX (hexadecimal) pairs,  |
|   |                                  | so expected field must have an even    |
|   |                                  | size and its contents must be in range |
|   |                                  | '0'-'9' or 'A'-'F' inclusive.          |
| 13| Bad signature field              | Means that the passed signature is of  |
|   |                                  | incorrect format. The expected format  |
|   |                                  | is of 40 characters formatted as 20 HEX|
|   |                                  | (hexadecimal) pairs.                   |
| 14| Z closure time limit             | Means that 24 hours passed from the    |
|   |                                  | last Z closure. Issue a Z and retry.   |
| 15| Z closure not found              | The specified Z closure number does not|
|   |                                  | exist. Pass an existing Z number.      |
| 16| Z closure record bad             | The requested Z record is unreadable   |
|   |                                  | (damaged). Device requires service     |
| 17| User browsing in progress        | The user is accessing the device by    |
|   |                                  | manual operation. The protocol usage   |
|   |                                  | is suspended until the user terminates |
|   |                                  | the keyboard browsing. Just wait or    |
|   |                                  | inform application user.               |
| 18| Signature daily limit reached    | The max number of signatures in a day  |
|   |                                  | have been issued. A Z closure is needed|
|   |                                  | to free the daily storage memory.      |
| 19| Printer paper end detected       | Replace the paper roll and retry       |
| 1A| Printer is offline               | Printer disconnection. Service required|
| 1B| Fiscal unit is offline           | Fiscal disconnection. Service required.|
| 1C| Fatal hardware error             | Mostly fiscal errors. Service required.|
| 1D| Fiscal unit is full              | Need fiscal replacement. Service       |
| 1E| No data passed for signature     | Need to pass some data to close block  |
| 1F| Signature does not exist         | Correct requested signature number     |
| 20| Battery fault detected           | If problem persists, service required  |
| 21| Recovery in progress             | This command is not allowed when a     |
|   |                                  | recovery has started. Finish the       |
|   |                                  | recovery procedure and retry           |
| 22| Recovery only after CMOS reset   | Attempted to initiate a recovery       |
|   |                                  | procedure without a previous CMOS      |
|   |                                  | reset. The recovery is not needed.     |
| 23| Real-Time Clock needs programming| This means that the RTC has invalid    |
|   |                                  | data and needs to be reprogrammed. As  |
|   |                                  | a consequence, service is needed.      |
| 24| Z closure date warning           | This is an error returned by a closure |
|   |                                  | request, when the RTC's date has a     |
|   |                                  | value at least 48 hours later than the |
|   |                                  | last closure time stamp (see XZreport) |
| 25| Bad character in stream          | This error is returned when a stream   |
|   |                                  | sent contains one or more invalid      |
|   |                                  | characters. A table of allowed binary  |
|   |                                  | values is defined in 'table 4'. This   |
|   |                                  | error means that device has rejected   |
|   |                                  | the specified frame. A filtering of    |
|   |                                  | data sent to the device *must* be      |
|   |                                  | performed by host.                     |
+---+----------------------------------+----------------------------------------+


7.2. Table 2, ASCII control codes [CC1]
+-----------+-------+-------+-------------------------------------------------------+
|  Name     |  HEX  |  DEC  | Purpose                                               |
+-----------+-------+-------+-------------------------------------------------------+
| ACK       |  06h  |  6    | Acknowledge (positive)                                |
| NAK       |  15h  |  21   | Not Acknowledge (negative)                            |
| STX       |  02h  |  2    | Start of text                                         |
| ETX       |  03h  |  3    | End of text                                           |
| CAN       |  18h  |  24   | Cancel                                                |
| ENQ       |  05h  |  5    | Enquire                                               |
+-----------+-------+-------+-------------------------------------------------------+


7.3. Table 3, timeouts and retransmittions - minimum recommended values
+-----------------------------------------------------------+
| Enquire - ACKnowledge timeout:        3 secs, 3 retries   |
| Packet  - ACKnowledge timeout:        3 secs, 3 retries   |
| STX receive timeout:                  3 secs              |
| In packet data timeout:               1 secs              |
+-----------------------------------------------------------+


7.4. Table 4, Hexadecimal matrix of invalid binary values

   [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [A] [B] [C] [D] [E] [F]
[0] X   X   X   X   X   X   X   X   X   -   -   X   -   -   X   X    
[1] X   X   X   X   X   X   X   X   X   X   -   X   X   X   X   X 
[2] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   - 
[3] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   - 
[4] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   - 
[5] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   - 
[6] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   - 
[7] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   X 
[8] -   X   X   X   X   X   X   X   X   X   X   X   X   X   X   X 
[9] X   X   X   X   X   X   X   X   X   X   X   X   X   X   X   X 
[A] X   -   -   -   -   -   -   -   -   -   -   -   -   X   -   - 
[B] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   - 
[C] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   - 
[D] -   -   X   -   -   -   -   -   -   -   -   -   -   -   -   - 
[E] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   - 
[F] -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   X 

'X' denotes an invalid value, 
'-' denotes an acceptable value.







